package org.dakuo.sgfyModel;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import org.dakuo.renrenTool.RenrenLogin;

public class SgfyGame {
	private List<Cookie> cookieList;
	private ArrayList<SgfyVillage> villageL;
	private String email;
	private String password;
	private String hostURI;
	private ArrayList<SgfyAutoMissionCons> missionConsList;

	public SgfyGame(String email, String password, String hostURI) {
		cookieList = null;
		setVillageL(new ArrayList<SgfyVillage>());
		this.setEmail(email);
		this.setPassword(password);
		this.setHostURI(hostURI);
		missionConsList = new ArrayList<SgfyAutoMissionCons>();
	}
	
	public double dispatchMissionCons(){
		if(this.missionConsList!=null){
			
			for(SgfyAutoMissionCons mc:missionConsList){
				if(getVillageByName(mc.getVillageName())!=null){
					this.getVillageByName(mc.getVillageName()).addMissionCons(mc);
					double time = this.getVillageByName(mc.getVillageName()).doMissionCons();
					return time;
				
				}
				else
					return -1;
			}
		}
		System.out.println("No mission in GAME");
		return -1;
	}
	public SgfyVillage getVillageByName(String name){
		for(SgfyVillage v:this.getVillageL())
		if(v.getName().equals(name))
			return v;
		return null;
	}
	
	public boolean addMissionCons(String villageName,String consName,String consLevel){
		return this.missionConsList.add(new SgfyAutoMissionCons(villageName, consName, consLevel,this.cookieList,this.getHostURI()));
	}

	public SgfyVillage getMainVillage() {
		for (SgfyVillage vTemp : villageL) {
			if (vTemp.isMainVillage())
				return vTemp;
		}
		return null;
	}

//	public boolean updateCon(SgfyVillage village, String conName, String level) {
//		double duration = village.updateCons(conName, level, cookieList, hostURI);
//		if (duration!=-1)
//			return true;
//		else
//			return false;
//	}

	public boolean getVillageInfo(SgfyVillage village){
		List<Cookie> cookieTemp = village.getVillageInfo(cookieList, getHostURI());
		if (cookieTemp!=null){
			this.cookieList = cookieTemp;
			return true;
		}
		return false;
	}
	
	public boolean getVillageInfoById(String id) {
		for (SgfyVillage vTemp : villageL) {
			if (vTemp.getId().equals(id)) {
				List<Cookie> cookieTemp = vTemp.getVillageInfo(cookieList, getHostURI());
				if (cookieTemp!=null){
					this.cookieList = cookieTemp;
					return true;
				}
			}
		}
		return false;
	}
	public boolean getVillageInfoByName(String name) {
		for (SgfyVillage vTemp : villageL) {
			if (vTemp.getName().equals(name)) {
				List<Cookie> cookieTemp = vTemp.getVillageInfo(cookieList, getHostURI());
				if (cookieTemp!=null){
					this.cookieList = cookieTemp;
					return true;
				}
			}
		}
		return false;
	}

	public boolean login() {
		// TODO find way across RENREN to login
		cookieList = RenrenLogin.login(getEmail(), getPassword());
		if (cookieList != null) {
			if (sanguoLogin() != false)
				return true;
			else
				return false;
		}
		return false;
	}

	/**
	 * login sanguo & identify main village ID
	 */

	public boolean sanguoLogin() {
		try {
			DefaultHttpClient httpClient = new DefaultHttpClient();

			Iterator<Cookie> ci = cookieList.iterator();
			while (ci.hasNext())
				httpClient.getCookieStore().addCookie(ci.next());

			HttpGet httpGet = new HttpGet(getHostURI());

			httpGet
					.setHeader(
							"User-Agent",
							"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)");
			httpGet
					.addHeader("Accept",
							"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
			httpGet.addHeader("Accept-Language", "en-us,en;q=0.5");
			httpGet.addHeader("Accept-Charset",
					"ISO-8859-1,utf-8;q=0.7,*;q=0.7");
			httpGet.addHeader("Content-Type",
					"application/x-www-form-urlencoded");

			HttpResponse response = httpClient.execute(httpGet);
			HttpEntity entity = response.getEntity();

			String location = "";
			// If the response does not enclose an entity, there is no need
			// to bother about connection release
			if (entity != null) {
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(entity.getContent()));
				try {
					String line = reader.readLine();
					while (line != null) {
						if (line.contains("location")) {
							location = line.substring(line
									.indexOf("location=\"") + 10, line
									.lastIndexOf("\";"));
							System.out.println("Sanguo login get1 done");
						}
						line = reader.readLine();
					}

				} catch (IOException ex) {

					// In case of an IOException the connection will be released
					// back to the connection manager automatically
					throw ex;

				} catch (RuntimeException ex) {

					// In case of an unexpected exception you may want to abort
					// the HTTP request in order to shut down the underlying
					// connection and release it back to the connection manager.
					httpGet.abort();
					throw ex;

				} finally {

					// Closing the input stream will trigger connection release
					reader.close();

				}
			}
			if (entity != null)
				entity.consumeContent();

			// second get
			httpGet.setURI(new URI(getHostURI() + location));
			response = httpClient.execute(httpGet);
			entity = response.getEntity();
			if (entity != null) {
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(entity.getContent()));
				try {
					String line = reader.readLine();
					while (line != null) {
						if (line.contains("location")) {
							location = line.substring(line
									.indexOf("location=\"") + 10, line
									.lastIndexOf("\";"));
							System.out.println("Sanguo login get2 done");
						}
						line = reader.readLine();
					}

				} catch (IOException ex) {

					// In case of an IOException the connection will be released
					// back to the connection manager automatically
					throw ex;

				} catch (RuntimeException ex) {

					// In case of an unexpected exception you may want to abort
					// the HTTP request in order to shut down the underlying
					// connection and release it back to the connection manager.
					httpGet.abort();
					throw ex;

				} finally {

					// Closing the input stream will trigger connection release
					reader.close();

				}
			}
			// third get
			httpGet.setURI(new URI(location));
			response = httpClient.execute(httpGet);
			entity = response.getEntity();
			if (entity != null) {
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(entity.getContent()));
				try {
					String line = reader.readLine();
					while (line != null) {
						if (line.contains("_uUES('")) {
							location = line.substring(
									line.indexOf("_uUES('") + 7, line
											.lastIndexOf("')"));
						}
						line = reader.readLine();
					}

				} catch (IOException ex) {

					// In case of an IOException the connection will be released
					// back to the connection manager automatically
					throw ex;

				} catch (RuntimeException ex) {

					// In case of an unexpected exception you may want to abort
					// the HTTP request in order to shut down the underlying
					// connection and release it back to the connection manager.
					httpGet.abort();
					throw ex;

				} finally {

					// Closing the input stream will trigger connection release
					reader.close();

				}
			}
			// forth get
			httpGet.setURI(new URI(location));
			httpGet.addHeader("Referer",
					"http://user.unite.kunlun.com/User/uniteLogout?ref="
							+ getHostURI());
			response = httpClient.execute(httpGet);
			entity = response.getEntity();
			if (entity != null) {
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(entity.getContent()));
				try {
					String line = reader.readLine();
					while (line != null) {
						if (line.contains("_uUES('")) {
							location = line.substring(
									line.indexOf("_uUES('") + 7, line
											.lastIndexOf("')"));
							System.out.println("Sanguo login get4 done");
						}
						line = reader.readLine();
					}

				} catch (IOException ex) {

					// In case of an IOException the connection will be released
					// back to the connection manager automatically
					throw ex;

				} catch (RuntimeException ex) {

					// In case of an unexpected exception you may want to abort
					// the HTTP request in order to shut down the underlying
					// connection and release it back to the connection manager.
					httpGet.abort();
					throw ex;

				} finally {

					// Closing the input stream will trigger connection release
					reader.close();

				}
			}

			// 5th get
			httpGet.setURI(new URI(getHostURI()));
			response = httpClient.execute(httpGet);
			entity = response.getEntity();
			if (entity != null) {
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(entity.getContent()));
				try {
					String line = reader.readLine();
					while (line != null) {
						if (line.contains("location")) {
							location = line.substring(line
									.indexOf("location=\"") + 10, line
									.lastIndexOf("\";"));
							System.out.println("Sanguo login get5 done");
						}
						line = reader.readLine();
					}

				} catch (IOException ex) {

					// In case of an IOException the connection will be released
					// back to the connection manager automatically
					throw ex;

				} catch (RuntimeException ex) {

					// In case of an unexpected exception you may want to abort
					// the HTTP request in order to shut down the underlying
					// connection and release it back to the connection manager.
					httpGet.abort();
					throw ex;

				} finally {

					// Closing the input stream will trigger connection release
					reader.close();

				}
			}

			// 6th get
			httpGet.setURI(new URI(getHostURI() + location));
			response = httpClient.execute(httpGet);
			entity = response.getEntity();
			if (entity != null) {
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(entity.getContent()));
				try {
					String line = reader.readLine();
					while (line != null) {
						if (line.contains("location")) {
							location = line.substring(line
									.indexOf("location=\"") + 10, line
									.lastIndexOf("\";"));
							System.out.println("Sanguo login get6 done");
						}
						line = reader.readLine();
					}

				} catch (IOException ex) {

					// In case of an IOException the connection will be released
					// back to the connection manager automatically
					throw ex;

				} catch (RuntimeException ex) {

					// In case of an unexpected exception you may want to abort
					// the HTTP request in order to shut down the underlying
					// connection and release it back to the connection manager.
					httpGet.abort();
					throw ex;

				} finally {

					// Closing the input stream will trigger connection release
					reader.close();

				}
			}
			// Get main village id
			httpGet.setURI(new URI(getHostURI()));
			response = httpClient.execute(httpGet);
			entity = response.getEntity();

			String mainVillageId = "";
			if (entity != null) {
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(entity.getContent()));

				try {

					Pattern pCityId = Pattern.compile("w.villageid='(\\w+)';$",
							Pattern.DOTALL);

					// Matcher m;
					Matcher mCityId;
					
					String line = reader.readLine();

					while (line != null) {
						// m = p.matcher(line);
						mCityId = pCityId.matcher(line);
						if (mCityId.find()) {
							mainVillageId = mCityId.group(1);
							break;
						} else {

						}
						line = reader.readLine();
					}

				} catch (IOException ex) {

					throw ex;

				} catch (RuntimeException ex) {

					httpGet.abort();
					throw ex;

				} finally {

					reader.close();

				}
			}

			String inCityUrl = getHostURI()
					+ "index.php?act=build.status&villageid=" + mainVillageId
					+ "&rand=" + "775836";

			/**
			 * Get City list Info
			 */
			httpGet.setURI(new URI(inCityUrl));
			response = httpClient.execute(httpGet);
			entity = response.getEntity();
			if (entity != null) {
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(entity.getContent()));
				try {

					// Pattern p =
					// Pattern.compile("sgtitle=\"\\s+(\\W+)(\\s+)Lv.(\\d+)(\\s+)\".*(MM_xmlLoad\\(')(\\w+\\.\\w+\\&\\w+=\\d+)(.*/>$)",Pattern.DOTALL);
					// Pattern pEmpty =
					// Pattern.compile("sgtitle=\"(\\s)+(空地)(\\s+).*(MM_xmlLoad\\(')(\\w+\\.\\w+\\&\\w+=\\d+)(.*/>$)",Pattern.DOTALL);
					// Pattern pResource =
					// Pattern.compile("<reso\\sid=\"(\\w+)\"\\snow=\"(\\d+(.\\d+)*)\"\\smax=\"(\\d+(.\\d+)*)\"\\sspeed=\"(\\d+(.\\d+)*)\"\\sincrease=\"(\\d+(.\\d+)*)\"\\s(buff=\"(\\d+(.\\d+)*)\")*");
					Pattern pVillageInfo = Pattern
							.compile("<village\\sid=\"(\\d+)\"\\sname=\"(\\W+)\"\\sx=\"(\\d+)\"\\sy=\"(\\d+)\"\\sstate=\"(\\W+)\"\\sismain=\"(\\d)\"\\sisstatevillage=\"(\\d)\"\\s/>$");

					// Matcher m;
					// Matcher mEmpty;
					// Matcher mResource;
					Matcher mVillageInfo;

					String line = reader.readLine();
					while (line != null) {
						mVillageInfo = pVillageInfo.matcher(line);

						if (mVillageInfo.find()) {

							this.villageL.add(new SgfyVillage(mVillageInfo
									.group(1), mVillageInfo.group(2),
									mVillageInfo.group(3), mVillageInfo
											.group(4), mVillageInfo.group(5),
									mVillageInfo.group(6)));
						}
					line = reader.readLine();
					}

				} catch (IOException ex) {

					throw ex;

				} catch (RuntimeException ex) {

					httpGet.abort();
					throw ex;

				} finally {

					reader.close();

				}
			}
			cookieList = httpClient.getCookieStore().getCookies();

			httpClient.getConnectionManager().shutdown();
			return true;

		} catch (Exception e) {

			System.out.println(e.getStackTrace());
			return false;
		}
	}

	public void setVillageL(ArrayList<SgfyVillage> villageL) {
		this.villageL = villageL;
	}

	public ArrayList<SgfyVillage> getVillageL() {
		return villageL;
	}

	public static void main(String[] arg) {
		 SgfyGame game = new SgfyGame("xymlem","..11aaAA","http://x58.sanguo.renren.com/");
//		SgfyGame game = new SgfyGame("xymlem", "..11aaAA","http://h2.sanguo.renren.com/");

		game.login();
		// if(game.updateCon(game.getMainVillage(), "林场", "4"))
		// System.out.println("well update");
		if(game.getVillageInfo(game.getMainVillage()))
			System.out.println(game.getVillageL());
		game.addMissionCons("新的开始", "农田", "3");
		
		double duration = game.dispatchMissionCons();
		if(duration!=-1)
			System.out.println("Game dispatch mission Success"+duration);
		else
			System.out.println("Game dispatch mission fail");
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getEmail() {
		return email;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getPassword() {
		return password;
	}

	public void setHostURI(String hostURI) {
		this.hostURI = hostURI;
	}

	public String getHostURI() {
		return hostURI;
	}

}
